Skip to content

fix(pipeline): allow resuming a snapshot paused on a later loop visit - #12152

Closed
Anai-Guo wants to merge 1 commit into
deepset-ai:mainfrom
Anai-Guo:fix-resume-loop-blocked
Closed

fix(pipeline): allow resuming a snapshot paused on a later loop visit#12152
Anai-Guo wants to merge 1 commit into
deepset-ai:mainfrom
Anai-Guo:fix-resume-loop-blocked

Conversation

@Anai-Guo

Copy link
Copy Markdown

Related Issues

Fixes #12145

Proposed Changes

Resuming a pipeline from a pipeline_snapshot failed with PipelineComponentsBlockedError when the breakpoint had been hit on the second (or later) visit of a component inside a loop. First-visit resume worked; later-visit resume did not.

Root cause. When a snapshot is created, the paused component's inputs are stored and later restored through _convert_to_internal_format, which marks every restored input with sender = None — i.e. they look like user inputs. In has_any_trigger, a user input can only trigger a component on its first visit (component["visits"] == 0). On a loop re-visit the restored component_visits for that component is already >= 1, so:

  • trigger_from_predecessor is False (sender is None),
  • trigger_from_user is False (gated on visits == 0),
  • trigger_without_inputs is False (the component has senders),

so the component the run is supposed to resume at is marked BLOCKED and never selected, and the pipeline reports itself blocked.

Fix. The run already knows which component it is resuming at (pipeline_snapshot.break_point.component_name). When filling the initial priority queue, that component is now flagged as a resume target so it can trigger exactly once regardless of its visit count. The flag is only set during the initial fill on the resume path; every other queue fill (normal runs, the async path, and mid-loop refills) is unchanged, so a resumed component continues to be driven by predecessor triggers on subsequent iterations.

Changes:

  • has_any_trigger gains a trigger_from_resume condition (active only when the component carries the is_resume marker and has restored inputs).
  • _fill_queue accepts an optional resume_component_name and tags that one component.
  • Pipeline.run passes the resume component name into the initial _fill_queue call.

How did you test it?

  • Added a regression test (test_resume_snapshot_taken_on_a_later_loop_visit) reproducing the issue exactly (breakpoint on visit_count=1 inside a BranchJoiner loop), asserting the resume no longer raises and finishes the loop.
  • Verified manually that a normal (no-breakpoint) run, first-visit resume (visit_count=0), and pausing/resuming a non-greedy component on a later visit all behave correctly.
  • The existing test/core/pipeline/test_component_checks.py suite (74 tests) still passes.

Notes

Scope is limited to the reported PipelineComponentsBlockedError. An orthogonal, pre-existing snapshot-resume limitation involving greedy joiners over multiple loop hops (reproducible on main without this change) is intentionally left out of scope.


This PR was written with AI assistance (Claude Code) and reviewed by me before submission.

🤖 Generated with Claude Code

When a breakpoint fired on the second-or-later visit of a component inside a
loop, resuming the snapshot immediately failed with PipelineComponentsBlockedError.
The paused component's inputs are restored as user inputs (sender is not preserved
through serialization), and user inputs only trigger a component on its first visit,
so the resumed component was never selected to run.

Flag the component the run resumes at as a resume target when filling the initial
priority queue, so it can trigger exactly once regardless of its visit count.

Fixes deepset-ai#12145
@Anai-Guo
Anai-Guo requested a review from a team as a code owner July 25, 2026 07:19
@Anai-Guo
Anai-Guo requested review from davidsbatista and removed request for a team July 25, 2026 07:19
@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

@Anai-Guo is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@HaystackBot

Copy link
Copy Markdown
Contributor

Hi @Anai-Guo, thanks a lot for your contribution! 🙏

We noticed that the Contributor License Agreement (CLA) check (license/cla) hasn't passed yet, so we've temporarily moved this PR to draft and paused the review assignment.

To get your PR reviewed, please sign the CLA via the link in the license/cla check below (or in the CLA bot comment). As soon as the check turns green, this PR will automatically be marked ready for review again and a reviewer will be re-assigned.

@HaystackBot
HaystackBot removed the request for review from davidsbatista July 25, 2026 08:59
@HaystackBot HaystackBot added the cla-pending PR is in draft until the contributor signs the CLA label Jul 25, 2026
@HaystackBot
HaystackBot marked this pull request as draft July 25, 2026 08:59
@sjrl

sjrl commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Closing as fixing in #12162

@sjrl sjrl closed this Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-pending PR is in draft until the contributor signs the CLA topic:core topic:tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resuming a pipeline snapshot after the first loop visit fails with PipelineComponentsBlockedError

4 participants